package cn.maihe.elg.operation.centers.epoint.sanming.handler.service;

import cn.maihe.elg.operation.centers.epoint.sanming.dto.handler.EpointGetGuaranteeInfoReq;
import cn.maihe.elg.operation.centers.epoint.sanming.dto.handler.EpointGetGuaranteeInfoResp;
import cn.maihe.elg.operation.centers.epoint.sanming.enums.EpointRespCodeEnum;
import cn.maihe.elg.operation.centers.epoint.sanming.exception.EpointException;
import cn.maihe.elg.operation.centers.epoint.sanming.handler.EpointCenterTradeService;
import cn.maihe.elg.operation.centers.supports.CenterTradeContext;
import cn.maihe.elg.operation.centers.supports.annotation.CenterTradeService;
import cn.maihe.elg.operation.model.enums.*;
import cn.maihe.elg.operation.model.vo.order.AcceptOrderDetailVO;
import cn.maihe.elg.operation.repository.entity.AcceptOrderInfoDO;
import cn.maihe.elg.operation.repository.entity.BidCustomerDO;
import cn.maihe.elg.operation.repository.entity.GuaranteeAttachmentInfoDO;
import cn.maihe.elg.operation.repository.entity.ProjectInfoDO;
import cn.maihe.elg.operation.service.business.BidCustomerService;
import cn.maihe.elg.operation.service.business.ProjectInfoService;
import cn.maihe.elg.operation.service.order.AcceptOrderInfoService;
import cn.maihe.elg.operation.supports.system.ElgResourceService;
import cn.maihe.elg.operation.utils.DateUtil;
import cn.maihe.elg.operation.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.time.temporal.ChronoUnit;
import java.util.Base64;
import java.util.Date;

/**
 * @Description 开函后可通过该接口获取保函信息
 * @Author WJH
 * @Date 2021/04/20
 */
@CenterTradeService(
        provider = CenterProviderEnum.HYMAKE,
        centerNo = CenterNoEnum.SANMING_D,
        tradeType = TradeType.getbaohaninfo,
        reqClass = EpointGetGuaranteeInfoReq.class,
        respClass = EpointGetGuaranteeInfoResp.class
)
@Slf4j
public class EpointGetBaohanInfoService extends EpointCenterTradeService<EpointGetGuaranteeInfoReq, EpointGetGuaranteeInfoResp> {


    @Resource
    private AcceptOrderInfoService acceptOrderInfoService;

    @Resource
    private ElgResourceService resourceService;
    @Resource
    private BidCustomerService bidCustomerService;
    @Resource
    private ProjectInfoService projectInfoService;

    @Override
    protected void verifyParam(CenterTradeContext<EpointGetGuaranteeInfoReq, EpointGetGuaranteeInfoResp> context) {
        super.verifyParam(context);
        EpointGetGuaranteeInfoReq req = context.getReq();
        AcceptOrderInfoDO acceptOrderInfoDO = acceptOrderInfoService.getByCenterOrderId(context.getCenterId(), context.getOrgId(), req.getApplyno());
        Assert.notNull(acceptOrderInfoDO, () -> "查无此业务流水号申请记录");

//        if (!req.getBaohanno().equals(acceptOrderInfoDO.getGuaranteeNo())) {
//            throw EpointException.error("查无此业务流水关联保函编号记录");
//        }

        AcceptOrderStatus status = AcceptOrderStatus.resolve(acceptOrderInfoDO.getStatus());
        if (status != AcceptOrderStatus.HAS_OUT_GUARANTEE && status != AcceptOrderStatus.FINISH) {
            throw EpointException.error("申请保函状态非已开函，暂无法查询");
        }

        context.setAttr("acceptOrderInfoDO", acceptOrderInfoDO);
    }

    private String toUrl(GuaranteeAttachmentInfoDO attachmentInfoDO) {
        if (attachmentInfoDO != null && attachmentInfoDO.getFilePath() != null) {
            return resourceService.fmtSpIdNoAuthDownloadUrl(attachmentInfoDO.getAcceptOrderNo(), AttachmentFileType.resolve(attachmentInfoDO.getType()));
        }
        return null;
    }

    private String toBase64(GuaranteeAttachmentInfoDO attachmentInfoDO) {
        try {
            File file = resourceService.getFileByRelativePath(attachmentInfoDO.getFilePath());
            if (file != null && file.exists()) {
                byte[] fileByte = Files.readAllBytes(file.toPath());
                return Base64.getEncoder().encodeToString(fileByte);
            }
            throw new RuntimeException("文件不存在");
        } catch (IOException e) {
            throw new RuntimeException("文件base64编码异常:" + e.getMessage(), e);
        }
    }

    private String toUpMd5(GuaranteeAttachmentInfoDO attachmentInfoDO) {
        if (attachmentInfoDO != null && attachmentInfoDO.getFileMd5() != null) {
            return attachmentInfoDO.getFileMd5().toUpperCase();
        }
        return null;
    }

    @Override
    public EpointGetGuaranteeInfoResp processService(CenterTradeContext<EpointGetGuaranteeInfoReq, EpointGetGuaranteeInfoResp> context) {
        AcceptOrderInfoDO acceptOrderInfoDO = context.getAttr("acceptOrderInfoDO");
        AcceptOrderDetailVO vo = acceptOrderInfoService.getAcceptOrderDetailById(acceptOrderInfoDO.getId());
        EpointGetGuaranteeInfoResp infoResp = new EpointGetGuaranteeInfoResp();
        EpointGetGuaranteeInfoResp.RespData respData = new EpointGetGuaranteeInfoResp.RespData();
        BidCustomerDO bidCustomer = bidCustomerService.selectById(acceptOrderInfoDO.getBidCustomerId());
        ProjectInfoDO projectInfo = projectInfoService.selectById(acceptOrderInfoDO.getProjectId());
        try {
            //是	保函文件下载地址
            respData.setBaohanurl(toUrl(vo.getAllOFDFile()));
            //是	保函文件的base64码
            respData.setBaohanfile(toBase64(vo.getAllOFDFile()));
            //是	电子保函文件大写MD5
            respData.setGuaranteemd5(toUpMd5(vo.getAllOFDFile()));
            // 是	付保费银行账户户名
            respData.setPayername(bidCustomer.getBankUserName());
            // 是	支付保费银行账户号码
            respData.setPayeraccount(bidCustomer.getBankCardNum());
            /**是	费率*/
            respData.setRate(StringUtil.divide(acceptOrderInfoDO.getFeeRate(),4));
            //是	费用
            respData.setCost(fen2yuanString(Long.valueOf(vo.getGuaranteeFee())));
            respData.setPaytype("转账");
            respData.setTbysq(String.valueOf(projectInfo.getValidPeriod())); //是	投标保函有效期
            respData.setServicebegintime(DateUtil.formateDate(vo.getBidOpenTime(), "yyyy-MM-dd HH:mm:ss")); //是	保险起期
            respData.setServiceendtime(DateUtil.formateDate(Date.from(vo.getBidOpenTime().toInstant().plus(vo.getValidPeriod() + 28, ChronoUnit.DAYS)), "yyyy-MM-dd HH:mm:ss")); //是	保险止期
            respData.setBiddercontact(vo.getBidderContactName()); //是	投标人联系人姓名
            respData.setBiddercontacttel(vo.getBidderContactTel()); //是	投标人联系方式
            respData.setBidderaddress(vo.getBidderAddress()); //是	投标人地址
            respData.setBidderemail(vo.getBidderEamil()); //是	投标人邮箱
            respData.setBidderpersonname(vo.getLegalPersonName()); //是	投标人法定代表人姓名
            respData.setBidderpersoncard(vo.getLegalPersonIdcard()); //是	投标人法定代表人身份证件号码
            respData.setBidderpersontel(vo.getLegalPersonTel()); //是	投标人法定代表人联系方式
            respData.setOrderurl(toUrl(vo.getProtocolFile())); // 是	电子申请单文件下载地址
            respData.setOrdermd5(toUpMd5(vo.getProtocolFile())); // 是	电子申请单文件MD5码
            respData.setQualficationfileurl(toUrl(vo.getOrgQualificationFile())); //是	企业资质文件下载地址
            respData.setQualficationfilemd5(toUpMd5(vo.getOrgQualificationFile())); //是	企业资质文件大写MD5码
            respData.setBusinesslicenseurl(toUrl(vo.getOrgBusinessLicFile())); //是	企业营业执照下载地址
            respData.setBusinesslicensemd5(toUpMd5(vo.getOrgBusinessLicFile())); //是	企业营业执照大写MD5码
            respData.setGuaranteexmlurl(toUrl(vo.getGuaranteeXmlFile())); // 结构是	电子保函文件中的结构化数据XML文件下载地址
            respData.setGuaranteexmlmd5(toUpMd5(vo.getGuaranteeXmlFile())); //是	电子保函文件中的结构化数据XML文件的大写MD5
            respData.setPayfileurl(toUrl(vo.getReceiveProveFile())); //是	到账凭证下载地址
            infoResp.setData(respData);
            infoResp.setCode(EpointRespCodeEnum.SUCCESS.getRespCode());
            infoResp.setMessage(EpointRespCodeEnum.SUCCESS.getRespDesc());
        } catch (Exception e) {
            throw EpointException.error("获取保函信息异常：" + e.getMessage(), e);
        }
        return infoResp;
    }


}
